#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

class UnionSet {
public:
	UnionSet(int n) :fa(n + 1) {
		for (int i = 0; i <= n; i++)fa[i] = i;
	}
	int get(int x) {
		return fa[x] = (fa[x] == x ? x : get(fa[x]));
	}
	void merge(int a, int b) {
		fa[get(a)] = get(b);
	}

	vector<int> fa;
};

struct Data {
	int i, j, e; //存储关系
};

void solve(){
	int n, cnt = 0;
	cin >> n;
	vector<Data> arr(n);
	unordered_map<int, int> h; //哈希映射，因为i,j范围太大
	for (int i = 0; i < n; i++) {
		Data& x = arr[i];
		cin >> x.i >> x.j >> x.e;
		if (h.find(x.i) == h.end()) h[x.i] = cnt++; //如果i没出现过
		if (h.find(x.j) == h.end()) h[x.j] = cnt++;
	}
	UnionSet u(2 * n);
	for (int i = 0; i < n; i++) {
		if (arr[i].e == 0)continue; //不等管旭
		u.merge(h[arr[i].i], h[arr[i].j]); //给映射的边建立关系
	}
	int flag = 1;
	for (int i = 0; i < n && flag; i++) {
		if (arr[i].e == 1) continue;  
		if (u.get(h[arr[i].i]) == u.get(h[arr[i].j])) { //两边不相等，但是处于同一集合，故矛盾
			flag = 0;
		}
	}
	if (flag == 1) cout << "YES" << "\n";
	else cout << "NO" << "\n";
}


int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin >> t;

	while (t--){
		solve();
	}

	return 0;
}